"""
增强版回调数据管理模块
基于原有回调脚本，集成到Flask应用中，保持100%向后兼容
"""
import os
import json
import time
import logging
from datetime import datetime
from typing import Dict, List, Any, Optional
from flask import Blueprint, request, jsonify, current_app
from app.utils.mysql_db import get_db_connection
from app.utils.logger import log_api_call

# 创建蓝图
bp = Blueprint("callback_enhanced", __name__)

# 全局变量
callback_service_status = {
    "running": True,  # 默认启动状态
    "start_time": datetime.now().isoformat(),
    "total_received": 0,
    "last_receive_time": None,
    "storage_mode": "database"  # 只使用数据库存储
}

# 配置
CALLBACK_PATH = os.environ.get("CALLBACK_PATH", "/callback")
JS_MAX_SAFE_INTEGER = 9007199254740991

def load_service_status():
    """从数据库加载服务状态"""
    conn = None
    try:
        conn = get_db_connection()
        with conn.cursor() as cur:
            # 获取服务状态
            cur.execute("""
                SELECT running, start_time, total_received, last_receive_time, storage_mode
                FROM callback_service_status 
                WHERE service_name = 'default'
            """)
            status = cur.fetchone()
            
            if status:
                callback_service_status.update({
                    "running": bool(status['running']),
                    "start_time": status['start_time'].isoformat() if status['start_time'] else datetime.now().isoformat(),
                    "total_received": status['total_received'],
                    "last_receive_time": status['last_receive_time'],
                    "storage_mode": status['storage_mode']
                })
            
            # 获取数据总数
            cur.execute("SELECT COUNT(*) as total FROM callback_data")
            total_result = cur.fetchone()
            if total_result:
                callback_service_status["total_received"] = total_result['total']
        
        current_app.logger.info(f"已加载回调服务状态，总数据: {callback_service_status['total_received']} 条")
    except Exception as e:
        current_app.logger.error(f"加载服务状态失败: {e}")
    finally:
        if conn:
            conn.close()

def update_service_status():
    """更新服务状态到数据库"""
    conn = None
    try:
        conn = get_db_connection()
        with conn.cursor() as cur:
            cur.execute("""
                UPDATE callback_service_status 
                SET running = %s, total_received = %s, last_receive_time = %s, updated_at = NOW()
                WHERE service_name = 'default'
            """, (
                callback_service_status["running"],
                callback_service_status["total_received"],
                callback_service_status["last_receive_time"]
            ))
        conn.commit()
    except Exception as e:
        current_app.logger.error(f"更新服务状态失败: {e}")
    finally:
        if conn:
            conn.close()

def fix_long_fields(item):
    """修复超长整数字段"""
    for k, v in item.items():
        if isinstance(v, int) and abs(v) > JS_MAX_SAFE_INTEGER:
            item[k] = str(v)
    return item

def save_to_database(record):
    """保存数据到数据库"""
    conn = None
    try:
        conn = get_db_connection()
        with conn.cursor() as cur:
            cur.execute("""
                INSERT INTO callback_data (receive_time, receive_seq, data_json, created_at)
                VALUES (%s, %s, %s, %s)
            """, (
                record['receive_time'],
                record['receive_seq'], 
                json.dumps(record['data'], ensure_ascii=False),
                datetime.now()
            ))
        conn.commit()
    except Exception as e:
        current_app.logger.error(f"保存到数据库失败: {e}")
        raise
    finally:
        if conn:
            conn.close()

def get_next_receive_seq():
    """获取下一个接收序号"""
    conn = None
    try:
        conn = get_db_connection()
        with conn.cursor() as cur:
            cur.execute("SELECT COALESCE(MAX(receive_seq), 0) + 1 as next_seq FROM callback_data")
            result = cur.fetchone()
            return result['next_seq'] if result else 1
    except Exception as e:
        current_app.logger.error(f"获取序号失败: {e}")
        return 1
    finally:
        if conn:
            conn.close()

# ==================== 原有API（完全兼容） ====================

@bp.route(CALLBACK_PATH, methods=['POST'])
@bp.route('/api/callback', methods=['POST'])  # 前端代理路径别名
@log_api_call("callback.receive_data")
def generic_callback():
    """
    通用回调接口，接收任意第三方POST回调数据，支持单条json和json list
    原有API，保持100%兼容
    """
    # 检查数据接收状态
    if not callback_service_status["running"]:
        return jsonify({
            "code": 503,
            "message": "数据接收已停止，请先开启数据接收功能"
        }), 503
    
    start_time = time.time()
    try:
        # 获取请求数据（原有逻辑）
        data = request.json
        if not data:
            data = request.form.to_dict()
        if not data:
            data = request.values.to_dict()
        if not data:
            data = {"raw_body": request.data.decode("utf-8")}

        # 统一处理为list
        if isinstance(data, list):
            data_list = data
        else:
            data_list = [data]

        # 处理每一条数据
        results = []
        for item in data_list:
            item = fix_long_fields(item)
            receive_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
            receive_seq = get_next_receive_seq()
            
            # 存储结构
            record = {
                "receive_time": receive_time,
                "receive_seq": receive_seq,
                "data": item
            }
            
            # 保存到数据库
            save_to_database(record)
            
            results.append({
                "receive_seq": receive_seq,
                "receive_time": receive_time
            })

            # 更新状态
            callback_service_status["total_received"] = callback_service_status["total_received"] + 1
            callback_service_status["last_receive_time"] = receive_time
            
            # 更新数据库状态
            update_service_status()

            # 日志输出（原有格式）
            current_app.logger.info("━" * 50)
            current_app.logger.info(f"★ 接收到数据 #{receive_seq} ★")
            current_app.logger.info("┏━ 数据内容 ━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
            for k, v in item.items():
                current_app.logger.info(f"{k}: {v}")
            current_app.logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
            current_app.logger.info(f"当前总数: {callback_service_status['total_received']}")
            current_app.logger.info(f"处理耗时: {(time.time() - start_time)*1000:.2f}ms")
            current_app.logger.info("━" * 50)

        return jsonify({
            "code": 200,
            "message": "数据接收成功",
            "data": results if len(results) > 1 else results[0]
        })
        
    except Exception as e:
        current_app.logger.error(f"处理回调数据时出错: {str(e)}", exc_info=True)
        return jsonify({
            "code": 500,
            "message": f"处理数据出错: {str(e)}"
        }), 500

@bp.route('/stats', methods=['GET'])
@bp.route('/api/stats', methods=['GET'])  # 前端代理路径别名
@log_api_call("callback.get_stats")
def stats():
    """
    获取统计信息
    原有API，保持100%兼容
    """
    # 统计信息始终可查询，不受接收状态影响
    
    try:
        # 刷新状态
        load_service_status()
        
        result = {
            "code": 200,
            "data": {
                "total_received": callback_service_status["total_received"],
                "last_receive_time": callback_service_status["last_receive_time"]
            }
        }
        return jsonify(result)
    except Exception as e:
        current_app.logger.error(f"获取统计信息时出错: {str(e)}", exc_info=True)
        return jsonify({
            "code": 500,
            "message": f"获取统计信息出错: {str(e)}"
        }), 500

@bp.route('/clear', methods=['GET', 'POST'])
@bp.route('/api/clear', methods=['GET', 'POST'])  # 前端代理路径别名
@log_api_call("callback.clear_data")
def clear_data():
    """
    清除已接收的数据
    原有API，保持100%兼容
    """
    # 清除数据功能始终可用，不受接收状态影响
    
    conn = None
    try:
        key = request.args.get('key')
        value = request.args.get('value')
        cleared_count = 0
        
        conn = get_db_connection()
        with conn.cursor() as cur:
            if key and value is not None:
                # 清理指定key/value的数据
                cur.execute("""
                    SELECT COUNT(*) as count FROM callback_data 
                    WHERE JSON_EXTRACT(data_json, CONCAT('$.', %s)) = %s
                """, (key, value))
                count_result = cur.fetchone()
                cleared_count = count_result['count'] if count_result else 0
                
                cur.execute("""
                    DELETE FROM callback_data 
                    WHERE JSON_EXTRACT(data_json, CONCAT('$.', %s)) = %s
                """, (key, value))
                
                message = f"已清理 {cleared_count} 条数据"
            else:
                # 清理全部数据
                cur.execute("SELECT COUNT(*) as count FROM callback_data")
                count_result = cur.fetchone()
                cleared_count = count_result['count'] if count_result else 0
                
                cur.execute("DELETE FROM callback_data")
                
                # 重置服务状态
                cur.execute("""
                    UPDATE callback_service_status 
                    SET total_received = 0, last_receive_time = NULL, updated_at = NOW()
                    WHERE service_name = 'default'
                """)
                
                # 更新内存中的状态
                callback_service_status["total_received"] = 0
                callback_service_status["last_receive_time"] = None
                
                # 重置序号计数器
                global receive_seq_counter
                receive_seq_counter = 0
                
                message = f"已清理全部数据，共 {cleared_count} 条"
        
        conn.commit()
        
        return jsonify({
            "code": 200,
            "message": message
        })
    except Exception as e:
        current_app.logger.error(f"清除数据时出错: {str(e)}", exc_info=True)
        return jsonify({
            "code": 500,
            "message": f"清除数据出错: {str(e)}"
        }), 500
    finally:
        if conn:
            conn.close()


@bp.route('/data', methods=['GET'])
@bp.route('/api/data', methods=['GET'])  # 前端代理路径别名
@log_api_call("callback.get_data")
def get_data():
    """
    查看所有已接收的数据，支持多key和多key-value筛选
    原有API，保持100%兼容
    """
    # 查询数据功能始终可用，不受接收状态影响
    
    try:
        keys = request.args.getlist('key')
        values = request.args.getlist('value')
        
        # 修复中文编码问题 - 对keys和values都进行编码修复
        def fix_chinese_encoding(text):
            """修复Flask接收中文URL参数时的编码问题"""
            if not text:
                return text
            try:
                # 检查是否需要修复编码
                text.encode('ascii')
                return text  # 如果是纯ASCII，不需要修复
            except UnicodeEncodeError:
                try:
                    # 尝试修复编码
                    return text.encode('latin1').decode('utf-8')
                except:
                    # 如果修复失败，返回原文本
                    return text
        
        keys = [fix_chinese_encoding(key) for key in keys]
        values = [fix_chinese_encoding(value) for value in values]
        keyword = fix_chinese_encoding(request.args.get('keyword', '').strip())
        
        # 调试日志
        current_app.logger.info(f"查询参数 - keys: {keys}, values: {values}, keyword: '{keyword}'")
        conn = None
        conn = get_db_connection()
        try:
            with conn.cursor() as cur:
                # 构建查询条件
                where_conditions = []
                params = []
                
                # 关键词模糊搜索（在JSON数据中搜索）
                if keyword:
                    where_conditions.append("data_json LIKE %s")
                    params.append(f'%{keyword}%')
                
                # 原有的key-value精确搜索
                if keys:
                    for idx, key in enumerate(keys):
                        if len(values) == len(keys) and idx < len(values):
                            # 精确匹配 key-value
                            where_conditions.append("JSON_EXTRACT(data_json, CONCAT('$.', %s)) = %s")
                            params.extend([key, values[idx]])
                        else:
                            # 只检查key存在
                            where_conditions.append("JSON_EXTRACT(data_json, CONCAT('$.', %s)) IS NOT NULL")
                            params.append(key)
                
                # 构建完整查询
                query = "SELECT receive_time, receive_seq, data_json FROM callback_data"
                if where_conditions:
                    query += " WHERE " + " AND ".join(where_conditions)
                query += " ORDER BY receive_seq DESC"
                
                cur.execute(query, params)
                results = cur.fetchall()
                
                # 转换为原有格式
                filtered = []
                for row in results:
                    try:
                        data_json = json.loads(row['data_json']) if isinstance(row['data_json'], str) else row['data_json']
                        filtered.append({
                            "receive_time": row['receive_time'],
                            "receive_seq": row['receive_seq'],
                            "data": data_json
                        })
                    except Exception as e:
                        current_app.logger.error(f"解析JSON数据失败: {e}")
            
            return jsonify({
                "code": 200,
                "data": filtered,
                "count": len(filtered)
            })
        finally:
            if conn:
                conn.close()
    except Exception as e:
        current_app.logger.error(f"获取数据时出错: {str(e)}", exc_info=True)
        return jsonify({
            "code": 500,
            "message": f"获取数据出错: {str(e)}"
        }), 500

# ==================== 新增管理API ====================

@bp.route('/api/status', methods=['GET'])
@bp.route('/api/api/status', methods=['GET'])  # 前端代理路径别名
@log_api_call("callback.get_service_status")
def get_service_status():
    """获取服务状态 - 新增管理功能"""
    try:
        # 刷新状态
        load_service_status()
        
        # 计算运行时长
        if callback_service_status["start_time"]:
            try:
                start_time = datetime.fromisoformat(callback_service_status["start_time"])
                uptime_seconds = int((datetime.now() - start_time).total_seconds())
            except:
                uptime_seconds = 0
        else:
            uptime_seconds = 0
            
        # 获取数据库中的数据量
        conn = None
        try:
            conn = get_db_connection()
            with conn.cursor() as cur:
                cur.execute("SELECT COUNT(*) as count FROM callback_data")
                data_count_result = cur.fetchone()
                data_count = data_count_result['count'] if data_count_result else 0
        finally:
            if conn:
                conn.close()
            
        return {
            "running": callback_service_status["running"],
            "uptime_seconds": uptime_seconds,
            "total_received": callback_service_status["total_received"],
            "last_receive_time": callback_service_status["last_receive_time"],
            "storage_mode": callback_service_status["storage_mode"],
            "data_files": 0,  # 不再使用文件存储
            "memory_data_count": data_count
        }
    except Exception as e:
        return {"success": False, "error": str(e)}, 500

@bp.route('/api/control', methods=['POST'])
@bp.route('/api/api/control', methods=['POST'])  # 前端代理路径别名
@log_api_call("callback.control_service")
def control_service():
    """数据接收控制 - 新增管理功能"""
    conn = None
    try:
        action = request.json.get('action')
        
        conn = get_db_connection()
        with conn.cursor() as cur:
            if action == 'start':
                callback_service_status["running"] = True
                callback_service_status["start_time"] = datetime.now().isoformat()
                cur.execute("""
                    UPDATE callback_service_status 
                    SET running = 1, start_time = NOW(), updated_at = NOW()
                    WHERE service_name = 'default'
                """)
                message = "数据接收已开始"
                
            elif action == 'stop':
                callback_service_status["running"] = False
                cur.execute("""
                    UPDATE callback_service_status 
                    SET running = 0, updated_at = NOW()
                    WHERE service_name = 'default'
                """)
                message = "数据接收已停止"
                
            elif action == 'restart':
                callback_service_status["running"] = True
                callback_service_status["start_time"] = datetime.now().isoformat()
                cur.execute("""
                    UPDATE callback_service_status 
                    SET running = 1, start_time = NOW(), updated_at = NOW()
                    WHERE service_name = 'default'
                """)
                message = "数据接收已重启"
                
            else:
                return {"success": False, "error": "无效的操作"}, 400
        
        conn.commit()
        return {"message": message}
            
    except Exception as e:
        return {"success": False, "error": str(e)}, 500
    finally:
        if conn:
            conn.close()

@bp.route('/api/delete/<int:receive_seq>', methods=['DELETE'])
@bp.route('/api/api/delete/<int:receive_seq>', methods=['DELETE'])  # 前端代理路径别名
@log_api_call("callback.delete_single_data")
def delete_single_data(receive_seq):
    """删除单条数据 - 新增管理功能"""
    conn = None
    try:
        conn = get_db_connection()
        with conn.cursor() as cur:
            # 检查数据是否存在
            cur.execute("SELECT COUNT(*) as count FROM callback_data WHERE receive_seq = %s", (receive_seq,))
            count_result = cur.fetchone()
            
            if not count_result or count_result['count'] == 0:
                return {"success": False, "message": f"数据不存在 (序号: {receive_seq})"}, 404
            
            # 删除数据
            cur.execute("DELETE FROM callback_data WHERE receive_seq = %s", (receive_seq,))
            deleted_count = cur.rowcount
            
            if deleted_count > 0:
                # 更新统计信息
                cur.execute("""
                    UPDATE callback_service_status 
                    SET total_received = total_received - %s, updated_at = NOW()
                    WHERE service_name = 'default'
                """, (deleted_count,))
                
                # 更新内存状态
                callback_service_status["total_received"] = max(0, callback_service_status["total_received"] - deleted_count)
                
                conn.commit()
                current_app.logger.info(f"删除单条数据成功: 序号 {receive_seq}")
                
                return {
                    "success": True,
                    "message": f"成功删除数据 (序号: {receive_seq})",
                    "deleted_count": deleted_count
                }
            else:
                return {"success": False, "message": "删除失败"}, 500
        
    except Exception as e:
        current_app.logger.error(f"删除单条数据失败: {e}")
        return {"success": False, "error": str(e)}, 500
    finally:
        if conn:
            conn.close()

@bp.route('/api/export', methods=['GET'])
@bp.route('/api/api/export', methods=['GET'])  # 前端代理路径别名
@log_api_call("callback.export_data")
def export_data():
    """导出数据 - 新增管理功能"""
    conn = None
    try:
        format_type = request.args.get('format', 'json')
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        
        conn = get_db_connection()
        with conn.cursor() as cur:
            # 构建查询条件
            where_conditions = []
            params = []
            
            if start_date:
                where_conditions.append("DATE(created_at) >= %s")
                params.append(start_date)
            if end_date:
                where_conditions.append("DATE(created_at) <= %s")
                params.append(end_date)
            
            query = "SELECT receive_time, receive_seq, data_json FROM callback_data"
            if where_conditions:
                query += " WHERE " + " AND ".join(where_conditions)
            query += " ORDER BY receive_seq ASC"
            
            cur.execute(query, params)
            results = cur.fetchall()
            
            # 转换为原有格式
            filtered_data = []
            for row in results:
                try:
                    data_json = json.loads(row['data_json']) if isinstance(row['data_json'], str) else row['data_json']
                    filtered_data.append({
                        "receive_time": row['receive_time'],
                        "receive_seq": row['receive_seq'],
                        "data": data_json
                    })
                except Exception as e:
                    current_app.logger.error(f"解析JSON数据失败: {e}")
        
        return {
            "total_count": len(filtered_data),
            "export_data": filtered_data,
            "export_time": datetime.now().isoformat()
        }
        
    except Exception as e:
        return {"success": False, "error": str(e)}, 500
    finally:
        if conn:
            conn.close()

# 初始化服务状态
def init_callback_data():
    """初始化回调数据"""
    try:
        load_service_status()
    except Exception as e:
        current_app.logger.error(f"初始化回调数据失败: {e}")
